
// INCLUDES ********************************************************************

#include "FileUtils.h"

#include "Logger.h"

#include "Texture2D.h"

#include "TextureCache.h"

#include <stdexcept>

#include <thread>



// GLOBALS *********************************************************************

// NAMESPACES ******************************************************************

namespace
{
    void AddTextureAsync( const std::string& textureName)
    {
        Meteor::TextureCache::Instance().AddObject( textureName);
        
        Meteor::TextureCache::Instance().ObjectAdded( textureName);
    }

}


// *****************************************************************************

#pragma mark -
#pragma mark Constructor/Destructor
// -----------------------------------------------------------------------------

Meteor::TextureCache::TextureCache()

: Cache()

{

}

// -----------------------------------------------------------------------------

Meteor::TextureCache::~TextureCache()
{
    Flush();
}
    
#pragma mark -
#pragma mark Adding textures
// -----------------------------------------------------------------------------

Meteor::Texture2D* Meteor::TextureCache::AddObject( const std::string& fileName)
{
    if ( !fileName.compare("") || !Meteor::FileUtils::ResourceExists( fileName))
    {
        Meteor::Logger::DebugLog( "TextureCache::AddObject - Provided filename %s is invalid.",
                                  fileName.c_str());
        
        return nullptr;
    }
    
    std::string filePath = Meteor::FileUtils::ResourcePathForFile( fileName);
    
    Texture2D* newTexture = new Meteor::Texture2D( filePath);
    
    return Cache::AddObject( fileName, newTexture);
}

// -----------------------------------------------------------------------------

void Meteor::TextureCache::AddObjectAsync( const std::string& fileName, Meteor::Function* fileAdded)
{
    //! cache checks for doubled objects, but we don't want to create unnecessary
    //! threads, so double checking here
    if ( mAsyncFiles.find( fileName) != mAsyncFiles.end() ||
         mObjects.find( fileName) != mObjects.end())
    {
        Logger::DebugLog("TextureCache::AddObjectAsync - file already added.");
    
        return;
    }

    mAsyncFiles.insert( std::pair<std::string, Meteor::Function*>( fileName, fileAdded ));
    
    std::string filenameToUse = ( *mAsyncFiles.find( fileName)).first;

    std::thread addingThread( AddTextureAsync, filenameToUse);

    addingThread.detach();
}

